tfenvの.terraform-versionファイルにはバージョンベタ書きしなくてもOK
tfenv とは
大抵のプログラミング言語に**envってありますよね。それのTerraform版です。つまり Terraformの バージョン管理ツールです。これを使えばバージョンの異なるTerraform root module間でのTerraform バージョンの切り替えが容易に行なえます。
.terraform-version
ファイルに使いたいTerraform バージョンを書いて、root module(=terraform apply
などの各種Terraformコマンドを実行するディレクトリのこと)に置いておくと、Terraformコマンド実行時に自動的にそのバージョンのTerraformをインストールして、使ってくれます。
ちなみに anyenv経由でtfenvのインストールも可能です。
tfenvでちょっと面倒だったこと
Terraformのバージョンのアップグレード時です。.tf
ファイルのterraform
ブロック内のrequired_version
値を書き換えるのに加えて、.terraform-version
ファイルに書いているバージョンも書き換えないといけないことです。
まあ大した手間ではないのですが、たくさんのroot moduleを管理しているのでチリツモで面倒だなと感じていました。
実はバージョンベタ書きしなくてよかった
が、実はこの作業は別に必須ではありませんでした!.terraform-version
ファイルには、具体的なTerraformのバージョンを書く以外にいくつかの別の書き方があり、min-required
あるいはlatest-allowed
を使うとrequired_version
値に合致する適切なバージョンをインストール、使用してくれます。
この書き方を使えばバージョンのアップグレード時にもう.terraform-version
を修正する必要が無いですね。
min-required
required_version
値に合致する最小のバージョンをインストールします。
# 1.5.5をインストールします terraform { required_version = ">= 1.5.5" }
# 1.5.3をインストールします terraform { required_version = "~> 1.5.3" }
latest-allowed
required_version
値に合致する最大のバージョンをインストールします。
# 最大についての制限がないので、現在の最新版1.8.4をインストールします terraform { required_version = ">= 1.5.5" }
# 1.5.7(1.5系の最新バージョン)をインストールします terraform { required_version = "~> 1.5.3" }
min-required / latest-allowedどっちを使うべきか?
required_version
は以下いずれかの書き方を採用されている場合が多いのではないかと思います。
=
でバージョンを固定する~>
でパッチバージョンのアップグレードのみ許可する(例~> 1.8.0
)
1の場合min-required / latest-allowedで差はありません。最小も最大もない、固定ですからね。
2の場合、latest-allowedだとタイミングによって使われるバージョン(パッチバージョン)が変わってしまいます。~> 1.8.0
にした場合、今後1.8.5がリリースされれば1.8.5が使われる、といった感じです。これを許容できるかどうかがmin-required / latest-allowedの選定基準になると思います。個人的にはパッチバージョンとはいえ勝手に上がるのは嫌なので min-requiredを使いたいです。
注意点
required_version
に書かれているSemantic Versioning 2.0.0 をパースしているわけではなく、最初に見つかったバージョンを、最小限必要なバージョンの候補として使用する、とのことです。
つまりrequired_version
に複数個の条件を書いていても、2個目以降の条件は無視します。
例えば、.terraform-version
にmin-required
と書いていて、かつ以下の設定の場合は 1.7.0がインストールされます。
terraform { required_version = ">= 1.7.0, ~> 1.5.3" }
一方、条件を逆にすると
terraform { required_version = "~> 1.5.3, >= 1.7.0" }
この場合は 1.5.3がインストールされます。
child moduleのrequired_versionはチェックしない
required_version
はモジュールごとに書く事ができます。なのでchild moduleにも書いて、tfenvがそちらも読んで適切なバージョンをインストールしてくれるのか、調べてみました。
結論としては、tfenvはchild moduleのrequired_version
はチェックしないということがわかりました。
以下の方法で調査しました。
.terraform-version
にmin-required
と書く- root moduleの
required_version
に>= 1.7.0
と書く - child moduleの
required_version
に>= 1.7.3
と書く - → child module
required_version
もチェックしてくれるなら 1.7.3をインストールしてくれるはず - → 結果 「Unsupported Terraform Core version」になった (=root moduleの
required_version
だけ見てバージョンを決めたうえで、terraformコマンドを実行してエラーになっている)
Error: Unsupported Terraform Core version │ │ on modules/test/main.tf line 2, in terraform: │ 2: required_version = "~> 1.7.3" │ │ Module module.test (from ./modules/test) does not support Terraform version │ 1.7.0. To proceed, either choose another supported Terraform version or update │ this version constraint. Version constraints are normally set for good reason, │ so updating the constraint may lead to other errors or unexpected behavior.